import type {
  AxiosRequestConfig,
  CreateAxiosDefaults,
} from "axios";
import AxiosRequest from "./axiosRequest";

export interface RequestState {
  loading: boolean;
  error: Error;
  data: unknown;
  params: AxiosRequestConfig;
}

export interface YFWRequestOptions extends CreateAxiosDefaults {
  onBefore?: (params: AxiosRequestConfig) => void;
  onSuccess?: (data: unknown, params: AxiosRequestConfig) => void;
  onError?: (e: Error, params: AxiosRequestConfig) => void;
  onFinally?: (params: AxiosRequestConfig, data?: unknown, e?: Error) => void;

  // debounce
  debounceWait?: number;
  debounceLeading?: boolean;
  debounceTrailing?: boolean;
  debounceMaxWait?: number;

  // throttle
  throttleWait?: number;
  throttleLeading?: boolean;
  throttleTrailing?: boolean;

  // retry
  retryCount?: number;
  retryInterval?: number;
}

// 插件生命周期钩子
export interface ReturnPlugin {
  onBefore?: (params: AxiosRequestConfig) =>
    | ({
        stopNow?: boolean;
        returnNow?: boolean;
      } & Partial<RequestState>)
    | void;
  onSuccess?: (data: unknown, params: AxiosRequestConfig) => void;
  onError?: (e: Error, params: AxiosRequestConfig) => void;
  onFinally?: (params: AxiosRequestConfig, data?: unknown, e?: Error) => void;
  onCancel?: () => void;
  onMutate?: (data: unknown) => void;
}

export interface IPlugin {
  init?: (options: YFWRequestOptions) => Partial<RequestState>;
  (
    instance: AxiosRequest,
    options: YFWRequestOptions
  ): ReturnPlugin;
}
